﻿@implements IDisposable

@inject IUserBasketService basketService
@inject NavigationManager NavigationManager
@inject IUserService userService
@inject IUserConfigService userConfigService
@inject ILogger<BasketManager> logger

<DetailedErrorBoundary>
    <div class="SearchBox">
        <div class="SearchFieldIcon" title="Saved Baskets">
            <i class="fas fa-shopping-basket"/>
        </div>
        <select @bind="SelectedBasketId" class="SearchField">
            @foreach( var basket in baskets )
            {
                <option value="@basket.BasketId">@basket.Name @PrivateIndicator(basket)</option>
            }
        </select>
    </div>
</DetailedErrorBoundary>

@code {
    readonly List<Basket> baskets = new();
    string NewBasketName { get; set; }

    private int SelectedBasketId
    {
        get => basketService.CurrentBasket == null ? -1 : basketService.CurrentBasket.BasketId;
        set => _ = NewBasketSelected(value);
    }

    protected override async Task OnInitializedAsync()
    {
        await basketService.SwitchToDefaultBasket(userService.UserId);
        await base.OnInitializedAsync();
    }

    private async Task NewBasketSelected(int selectedBasketId)
    {
        logger.LogInformation($"Switching to basket: {selectedBasketId}");
        var newBasket = await basketService.SwitchToBasket(selectedBasketId);
        await userConfigService.SetForUser(ConfigSettings.SelectedBasketId, newBasket.BasketId.ToString());
        StateHasChanged();
    }

    private string PrivateIndicator(Basket basket)
    {
        if( userService.RolesEnabled )
        {
            // Shared baskets don't make sense if users and roles are disabled.
            if( basket != null && !basket.UserId.HasValue )
            {
                return "(shared)";
            }
        }

        return string.Empty;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if( firstRender )
        {
            basketService.OnBasketChanged += BasketsChanged;

            await LoadBasketList();

            // Restore the last-known basket
            var selectedBasketId = userConfigService.GetInt(ConfigSettings.SelectedBasketId);

            if( basketService.CurrentBasket != null && baskets.Any(x => x.BasketId == selectedBasketId) )
            {
                if( selectedBasketId > 0 && basketService.CurrentBasket.BasketId != selectedBasketId )
                    await basketService.SwitchToBasket(selectedBasketId);
            }
            else
            {
                await basketService.SwitchToDefaultBasket();
            }

            StateHasChanged();
        }
    }

    public void Dispose()
    {
        basketService.OnBasketChanged -= BasketsChanged;
    }

    private void BasketsChanged(BasketChanged change)
    {
        _ = LoadBasketList();
    }

    public async Task LoadBasketList()
    {
        var watch = new Stopwatch("LoadBaskets");

        ICollection<Basket> newBaskets = null;

        try
        {
            newBaskets = await basketService.GetUserBaskets(userService.UserId);
        }
        catch( Exception ex )
        {
            logger.LogWarning($"Unable to load baskets for user {userService.UserId}: {ex.Message}");
        }

        baskets.Clear();

        if( newBaskets != null )
            baskets.AddRange(newBaskets);

        watch.Stop();

        StateHasChanged();
    }

}